package com.wande.dataplatform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wande.common.core.utils.StringUtils;
import com.wande.common.mybatis.core.page.PageQuery;
import com.wande.common.mybatis.core.page.TableDataInfo;
import com.wande.dataplatform.domain.CleanRule;
import com.wande.dataplatform.domain.bo.CleanRuleBo;
import com.wande.dataplatform.domain.vo.CleanRuleVo;
import com.wande.dataplatform.mapper.CleanRuleMapper;
import com.wande.dataplatform.service.ICleanRuleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 数据清洗规则服务实现
 *
 * @author wande
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CleanRuleServiceImpl implements ICleanRuleService {

    private final CleanRuleMapper cleanRuleMapper;

    @Override
    public TableDataInfo<CleanRuleVo> queryPageList(CleanRuleBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<CleanRule> wrapper = buildQueryWrapper(bo);
        Page<CleanRule> page = cleanRuleMapper.selectPage(pageQuery.build(), wrapper);
        Page<CleanRuleVo> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        voPage.setRecords(BeanUtil.copyToList(page.getRecords(), CleanRuleVo.class));
        return TableDataInfo.build(voPage);
    }

    @Override
    public List<CleanRuleVo> queryList(CleanRuleBo bo) {
        LambdaQueryWrapper<CleanRule> wrapper = buildQueryWrapper(bo);
        List<CleanRule> list = cleanRuleMapper.selectList(wrapper);
        return BeanUtil.copyToList(list, CleanRuleVo.class);
    }

    @Override
    public CleanRuleVo queryById(Long id) {
        CleanRule entity = cleanRuleMapper.selectById(id);
        return BeanUtil.toBean(entity, CleanRuleVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insertByBo(CleanRuleBo bo) {
        CleanRule entity = BeanUtil.toBean(bo, CleanRule.class);
        cleanRuleMapper.insert(entity);
        return entity.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(CleanRuleBo bo) {
        CleanRule entity = BeanUtil.toBean(bo, CleanRule.class);
        return cleanRuleMapper.updateById(entity) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByIds(List<Long> ids) {
        return cleanRuleMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<CleanRuleVo> queryByDimension(String dimension) {
        LambdaQueryWrapper<CleanRule> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CleanRule::getDimension, dimension);
        wrapper.eq(CleanRule::getStatus, 1);
        wrapper.orderByDesc(CleanRule::getPriority);
        List<CleanRule> list = cleanRuleMapper.selectList(wrapper);
        return BeanUtil.copyToList(list, CleanRuleVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean importRules(List<CleanRuleBo> rules) {
        for (CleanRuleBo bo : rules) {
            insertByBo(bo);
        }
        return true;
    }

    private LambdaQueryWrapper<CleanRule> buildQueryWrapper(CleanRuleBo bo) {
        LambdaQueryWrapper<CleanRule> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotBlank(bo.getName()), CleanRule::getName, bo.getName());
        wrapper.eq(StringUtils.isNotBlank(bo.getCode()), CleanRule::getCode, bo.getCode());
        wrapper.eq(StringUtils.isNotBlank(bo.getDimension()), CleanRule::getDimension, bo.getDimension());
        wrapper.eq(StringUtils.isNotBlank(bo.getCleanType()), CleanRule::getCleanType, bo.getCleanType());
        wrapper.eq(bo.getStatus() != null, CleanRule::getStatus, bo.getStatus());
        wrapper.eq(bo.getProjectId() != null, CleanRule::getProjectId, bo.getProjectId());
        wrapper.orderByDesc(CleanRule::getPriority);
        wrapper.orderByDesc(CleanRule::getCreateTime);
        return wrapper;
    }
}
